C++ 객체의 생애 주기를 완전히 이해하는 것은 바로 힙과 스택내에서 존재하는 메커니즘을 장악하는 것입니다. 복사 제어는 클래스가 자신의 생명주기 를 두 가지 연산을 통해 관리하는 방식을 정의합니다: 복사 생성자 와 복사 대입 연산자입니다.
1. 초기화와 대입의 차이
직접 초기화(예: string dots(10, '.'))는 생성자를 직접 호출합니다. 그러나 복사 초기화 (string s2 = dots)는 복사 생성자를 사용합니다. 초기화와 달리, 대입 (trans = accum)은 기존 객체를 연산자=를 사용하여 덮어씁니다. 중요한 제약 조건은 복사 생성자의 매개변수가 참조형이어야 한다는 점입니다(const Foo&)이어야 합니다. 그렇지 않으면 값에 따라 인수를 전달하면 무한 재귀 루프 복사 호출의 무한 루프가 발생하게 됩니다.
2. 자동 생성의 역할
이 멤버들을 정의하지 않으면 컴파일러가 자동 생성된 버전을 제공합니다. 이 버전들은 멤버 단위 복사를 수행합니다. 하지만 간단한 타입에는 충분하지만, 동적 메모리를 관리하는 클래스에서는 종종 실패하며, 둔한 포인터나 중복 해제 문제를 유발할 수 있습니다.
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
Why must the first parameter of a copy constructor be a reference type (usually const)?
To allow the compiler to optimize the code into a move operation.
To prevent infinite recursion during parameter initialization.
Because pointers are not allowed in constructor signatures.
To ensure the object is placed on the heap rather than the stack.
✅ Correct!
Correct! If the parameter were passed by value, calling the copy constructor would require a copy of the argument, which would call the copy constructor again, infinitely.❌ Incorrect
Think about how arguments are passed. Passing by value requires a copy... and how is that copy made?QUESTION 2
What is the primary difference between Copy Initialization and Direct Initialization?
Direct initialization uses the assignment operator; copy initialization does not.
Copy initialization always requires the 'new' keyword.
Direct initialization asks the compiler to find the best constructor; copy initialization requires the copy constructor.
There is no functional difference; they are just different syntax for the same call.
✅ Correct!
Exactly. Copy initialization happens when using '=', passing by value, or returning by value, and specifically requires the copy/move constructor.❌ Incorrect
Direct initialization (using parens or braces) matches against all available constructors, while copy initialization specifically invokes the copy constructor.QUESTION 3
Assume 'numbered' has a synthesized copy constructor that copies a unique ID 'mysn'. What happens if you run: numbered a, b = a, c = b;?
Each object (a, b, c) will have a unique 'mysn' value.
The program will fail to compile because IDs cannot be copied.
All three objects will share the exact same 'mysn' value.
Object 'a' will be reset to zero after the copy.
✅ Correct!
Since the synthesized version performs memberwise copy, it simply duplicates the value of 'mysn' from the source, defeating the uniqueness.❌ Incorrect
The synthesized copy constructor does not 'know' that 'mysn' is supposed to be unique; it just copies the bits.QUESTION 4
Which of the following would trigger a compilation error if the constructor 'vector<int>(int size)' is marked 'explicit'?
vector<int> v(10);vector<int> v = 10;f(vector<int>(10));vector<int>* p = new vector<int>(10);✅ Correct!
Correct! 'explicit' prevents the use of a constructor in copy-initialization contexts (like using '=').❌ Incorrect
Explicit constructors can be used for direct initialization but not for implicit conversions or copy initialization using '='.QUESTION 5
What should a well-behaved copy-assignment operator usually return?
void
A copy of the current object by value.
A reference to the left-hand operand (*this).
The memory address of the right-hand operand.
✅ Correct!
This is a best practice to remain consistent with built-in types and allow assignment chaining (e.g., a = b = c).❌ Incorrect
To allow chaining and maintain standard C++ behavior, return a reference to the modified object.Case Study: Identifying Copy Logistics
Trace object construction and assignment
Analyze the following snippet:
Point global;
Point foo_bar(Point arg) {
Point local = arg;
Point *heap = new Point(global);
*heap = local;
Point pa[2] = { local, *heap };
return *heap;
}
Q
1. How many times is the copy constructor called in the execution of foo_bar?
Solution:
The copy constructor is called 6 times: 1. Passing 'arg' by value. 2. Initializing 'local'. 3. Dynamic construction of '*heap' from 'global'. 4. Initializing pa[0]. 5. Initializing pa[1]. 6. Initializing the return value from '*heap'.
The copy constructor is called 6 times: 1. Passing 'arg' by value. 2. Initializing 'local'. 3. Dynamic construction of '*heap' from 'global'. 4. Initializing pa[0]. 5. Initializing pa[1]. 6. Initializing the return value from '*heap'.
Q
2. Does the line '*heap = local' use the copy constructor?
Solution:
No. This is an assignment operation on an already existing object pointed to by 'heap'. It uses the copy-assignment operator (
No. This is an assignment operation on an already existing object pointed to by 'heap'. It uses the copy-assignment operator (
operator=), not the copy constructor.Q
3. If the 'Message' class used synthesized copy control while managing a list of 'Folders', what potential danger arises?
Solution:
A 'shallow copy' would occur. The new 'Message' would point to the same internal resources as the old one, but the 'Folders' wouldn't know about the new message. This leads to broken links or double-free errors when the messages are destroyed.
A 'shallow copy' would occur. The new 'Message' would point to the same internal resources as the old one, but the 'Folders' wouldn't know about the new message. This leads to broken links or double-free errors when the messages are destroyed.